package com.xiaoshuidi.cloud.module.rooms.framework.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiaoshuidi.cloud.module.rooms.framework.config.ConfigValues;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 百度地图工具类
 */
@Slf4j
@Component
public class BaiDuMapUtil {
    @Resource
    private ConfigValues configValues;

    /**
     * 公交
     */
    public static final String TRANSIT = "transit";
    /**
     * 步行
     */
    public static final String WALKING = "walking";
    /**
     * 骑行
     */
    public static final String RIDING = "riding";
    /**
     * 驾车
     */
    public static final String DRIVING = "driving";

    /**
     * 距离
     */
    public static final String DISTANCE = "distance";
    /**
     * 耗时
     */
    public static final String DURATION = "duration";

    /**
     * 地理位置编码
     *
     * @param address 地址
     * @return 经纬度 格式: 经度,维度
     */
    public String addressToLonLat(String address) {
        log.info("百度API-地址转经纬度, 请求地址:{}", address);
        String baiduAddressToLonLatUrl = configValues.getBaiduAddressToLonLatUrl();
        baiduAddressToLonLatUrl = StrUtil.format(baiduAddressToLonLatUrl, address, configValues.getBaiduAK());
        String resp = HttpUtil.get(baiduAddressToLonLatUrl);
        log.info("百度API-地址转经纬度, 请求地址:{}, 百度响应:{}", address, resp);
        JSONObject respJsonObj = JSONObject.parseObject(resp);
        if (!respJsonObj.get("status").toString().equals("0")) {
            return null;
        }
        JSONObject resultObj = (JSONObject) respJsonObj.get("result");
        JSONObject locationObj = (JSONObject) resultObj.get("location");
        String lng = locationObj.get("lng").toString();
        String lat = locationObj.get("lat").toString();
        log.info("百度API-地址转经纬度, 地址:{}, 经纬度:{}", address, lng + "," + lat);
        return lng + "," + lat;
    }

    /**
     * 地点检索
     */
    public String locationSearch(String address,String city) {
        log.info("百度API-地址检索, 请求地址:{}", address);
        String locationEntryPrompt = configValues.getLocationEntryPrompt().replace("*{region}",city);
        locationEntryPrompt = StrUtil.format(locationEntryPrompt, address, configValues.getBaiduAK(), "gcj02ll");
        String resp = HttpUtil.get(locationEntryPrompt);
        log.info("百度API-地址检索, 请求地址:{}, 百度响应:{}", address, resp);
        JSONObject respObj = JSONObject.parseObject(resp);
        if (!respObj.get("status").toString().equals("0")) {
            return null;
        }
        JSONArray result = (JSONArray) respObj.get("result");
        if (ObjectUtil.isEmpty(result)) {
            return null;
        }
        String lat = "";
        String lng = "";
        for (Object object : result) {
            JSONObject object1 = (JSONObject) object;
            String uid = object1.get("uid").toString();
            if (ObjectUtil.isEmpty(uid)) {
                continue;
            }
            JSONObject object2 = (JSONObject) object1.get("location");
            lat = object2.get("lat").toString();
            lng = object2.get("lng").toString();
            break;
        }
        log.info("百度API-地址检索, 地址:{}, 经纬度:{}", address, lng + "," + lat);
        return lng + "," + lat;
    }

    /**
     * 根据起点和终点规划步行路线
     *
     * @param origins     起点 格式: 经度,维度
     * @param destination 终点 格式: 经度,维度
     * @param method      通勤方式
     * @param type        时间/距离
     * @return 返回起点和终点距离
     */
    public Double walkingRoutePlanning(String origins, String destination, String method, String type) {
        // 原来用的高德格式是经度,纬度, 现在改用百度,格式换为纬度,经度, 这里需要转换一次
        if (StrUtil.isAllNotEmpty(origins, destination)) {
            String[] split = origins.split(",");
            origins = split[1] + "," + split[0];
            String[] split2 = destination.split(",");
            destination = split2[1] + "," + split2[0];
        }
        log.info("百度API-根据起点和终点规划步行路线, 起点:{}, 终点:{}", origins, destination);
        String baiduWalkingRoutePlanningUrl = configValues.getBaiduWalkingRoutePlanningUrl();
        baiduWalkingRoutePlanningUrl = StrUtil.format(baiduWalkingRoutePlanningUrl, method, origins, destination, configValues.getBaiduAK());
        String resp = HttpUtil.get(baiduWalkingRoutePlanningUrl);
        log.info("百度API-根据起点和终点规划步行路线, 起点:{}, 终点:{}, 百度响应:{}", origins, destination, resp);
        JSONObject respObj = JSONObject.parseObject(resp);
        if (!respObj.get("status").toString().equals("0")) {
            return 0d;
        }
        JSONObject resultObj = (JSONObject) respObj.get("result");
        JSONArray routesObj = (JSONArray) resultObj.get("routes");
        if (ObjectUtil.isEmpty(routesObj)) {
            return 0d;
        }
        JSONObject routeObj = (JSONObject) routesObj.get(0);
        if (type.equals(DISTANCE)) {
            Double distance = Double.valueOf(routeObj.get("distance").toString());
            log.info("百度API-根据起点和终点规划步行路线, 起点:{}, 终点:{}, 距离:{}米", origins, destination, distance);
            return distance;
        } else {
            Double duration = Double.valueOf(routeObj.get("duration").toString());
            log.info("百度API-根据起点和终点规划步行路线, 起点:{}, 终点:{}, 耗时:{}秒", origins, destination, duration);
            duration = BigDecimal.valueOf(duration).divide(BigDecimal.valueOf(60), 0, RoundingMode.HALF_UP).doubleValue();
            return duration;
        }
    }

}
